<script setup lang="ts">
import { ref, watch } from 'vue'
import { 
  SearchOutlined,
  ClockCircleOutlined,
  SmileOutlined
} from '@ant-design/icons-vue'

const httpStatus = ref('')
const result = ref<any>()
const StatusList = [
    {
        title: '1xx 信息性',
        child: [
            {
                title: '100 继续',
                content: '等待客户端发出请求的主体部分。'
            },
            {
                title: '101 切换协议',
                content: '服务器正在切换协议。'
            },
            {
                title: '102 处理中',
                content: '服务器正在处理请求，但尚未有响应可用。'
            },
            {
                title: '103 提前提示',
                content: '服务器提前向客户端提供关于其行为的提示。'
            }
        ]
    },
    {
        title: '2xx 成功',
        child: [
            {
                title: '200 成功',
                content: '请求已成功。'
            },
            {
                title: '201 已创建',
                content: '请求已被满足，并且创建了一个新的资源。'
            },
            {
                title: '202 已接受',
                content: '请求已被接受进行处理，但处理尚未完成。'
            },
            {
                title: '203 非权威性信息',
                content: '请求已成功处理，但返回的信息可能来自另一个来源。'
            },
            {
                title: '204 无内容',
                content: '请求已成功处理，但不返回任何内容。'
            },
            {
                title: '205 重置内容',
                content: '请求已成功处理，但不返回任何内容，并要求请求者重置文档视图。'
            },
            {
                title: '206 部分内容',
                content: '请求已部分满足，意味着只返回了资源的一部分。'
            },
            {
                title: '207 多状态',
                content: '跟随的消息体是一个 XML 消息，可以包含多个独立的响应代码。'
            },
            {
                title: '208 已报告',
                content: 'DAV 绑定的成员已经在对这个请求的先前回复中列举过，不会再次包括。'
            },
            {
                title: '226 IM 使用',
                content:
                    '服务器已经满足了对资源的请求，响应是应用到当前实例的一个或多个实例操作结果的表示。'
            }
        ]
    },
    {
        title: '3xx 重定向',
        child: [
            {
                title: '300 多种选择',
                content: '请求有多种可能的响应。'
            },
            {
                title: '301 永久移动',
                content:
                    '请求的资源已经被分配了一个新的永久 URI,未来的引用应该使用所包含的 URI 之一。'
            },
            {
                title: '302 查找',
                content: '请求的资源临时位于不同的 URI 下。'
            },
            {
                title: '303 查看其他位置',
                content:
                    '请求的响应可以在不同的 URI 下找到，应该通过在该资源上使用 GET 方法来获取。'
            },
            {
                title: '304 未修改',
                content: '请求的资源自上次请求以来未被修改。'
            },
            {
                title: '305 使用代理',
                content: '必须通过 Location 字段给出的代理访问请求的资源。'
            },
            {
                title: '306 切换代理',
                content: '不再使用。'
            },
            {
                title: '307 临时重定向',
                content: '请求的资源临时位于不同的 URI 下，应该使用临时重定向获取。'
            },
            {
                title: '308 永久重定向',
                content:
                    '请求的资源已经被分配了一个新的永久 URI，未来的引用应该使用所包含的 URI 之一。'
            }
        ]
    },
    {
        title: '4xx 客户端错误',
        child: [
            {
                title: '400 错误请求',
                content: '由于语法错误，无法满足请求。'
            },
            {
                title: '401 未授权',
                content: '请求需要用户认证。'
            },
            {
                title: '402 需要付款',
                content: '未使用。'
            },
            {
                title: '403 禁止',
                content: '服务器理解请求，但拒绝执行。'
            },
            {
                title: '404 未找到',
                content: '服务器找不到请求的资源。'
            },
            {
                title: '405 方法不允许',
                content: '服务器不支持请求的方法，无法处理。'
            },
            {
                title: '406 不可接受',
                content: '服务器无法生成客户端可接受的响应。'
            },
            {
                title: '407 需要代理认证',
                content: '客户端必须首先用代理认证自己。'
            },
            {
                title: '408 请求超时',
                content: '服务器等待请求时超时。'
            },
            {
                title: '409 冲突',
                content: '由于与资源的当前状态冲突，请求无法完成。'
            },
            {
                title: '410 已删除',
                content: '请求的资源不再可用，并且不会再可用。'
            },
            {
                title: '411 需要长度',
                content: '未定义 "Content-Length"。'
            },
            {
                title: '412 前提条件失败',
                content: '服务器评估请求中给出的前提条件为假。'
            },
            {
                title: '413 负载过大',
                content: '请求实体大于服务器定义的限制。'
            },
            {
                title: '414 请求 URI 过长',
                content: '客户端请求的 URI 比服务器愿意解释的更长。'
            },
            {
                title: '415 不支持的媒体类型',
                content: '请求的数据格式不受服务器支持。'
            },
            {
                title: '416 请求范围不符合要求',
                content: '请求中 Range 头字段指定的范围不能满足。'
            },
            {
                title: '417 期望值失败',
                content: '请求中的期望值不能由服务器满足。'
            },
            {
                title: '418 我是一个茶壶',
                content: '服务器拒绝煮咖啡，因为它是一个茶壶。'
            },
            {
                title: '421 请求被误导向',
                content: '请求被导向到一个无法产生响应的服务器。'
            },
            {
                title: '422 无法处理的实体',
                content: '请求格式正确，但由于语义错误而无法遵循。'
            },
            {
                title: '423 上锁',
                content: '访问的资源被锁定。'
            },
            {
                title: '424 失败依赖',
                content: '由于先前请求失败，导致此请求失败。'
            },
            {
                title: '426 升级所需',
                content: '客户端应该切换到不同的协议。'
            },
            {
                title: '428 需要前提条件',
                content: '源服务器要求请求是条件性的。'
            },
            {
                title: '429 请求过多',
                content: '用户在给定时间内发送了太多请求（“速率限制”）。'
            },
            {
                title: '431 请求头字段太大',
                content: '服务器不愿意处理请求，因为它的头字段太大。'
            },
            {
                title: '451 因法律原因不可用',
                content: '服务器因法律要求拒绝访问资源。'
            }
        ]
    },
    {
        title: '5xx 服务器错误',
        child: [
            {
                title: '500 内部服务器错误',
                content: '服务器遇到了一个意外情况，阻止了它完成请求。'
            },
            {
                title: '501 未实现',
                content: '服务器不支持为完成请求所需的功能。'
            },
            {
                title: '502 错误网关',
                content: '服务器从上游服务器收到了无效的响应。'
            },
            {
                title: '503 服务不可用',
                content: '由于临时过载或计划维护，服务器当前无法处理请求。'
            },
            {
                title: '504 网关超时',
                content: '服务器没有及时从上游服务器收到响应。'
            },
            {
                title: '505 HTTP 版本不支持',
                content: '服务器不支持请求中使用的 HTTP 协议版本。'
            },
            {
                title: '506 变体协商',
                content: '请求的透明内容协商导致了循环引用。'
            },
            {
                title: '507 存储空间不足',
                content: '服务器无法存储完成请求所需的表示。'
            },
            {
                title: '508 检测到循环',
                content: '服务器在处理请求时检测到了无限循环。'
            },
            {
                title: '510 未扩展',
                content: '需要对请求进行进一步扩展，服务器才能满足它。'
            },
            {
                title: '511 需要网络认证',
                content: '客户端需要认证以获得网络访问权限。'
            }
        ]
    }
]
watch(httpStatus, () => {
    for (let status of StatusList) {
        result.value = status.child.find((child) =>
            child?.title.split(' ').includes(httpStatus.value)
        )
        if (result.value) break
    }
},{immediate: true})

// 在原有代码基础上新增以下方法
const activeCategory = ref<string[]>([])
const lastSearchTime = ref('')

const handleSearch = () => {
  lastSearchTime.value = new Date().toLocaleTimeString()
}

const selectStatus = (item: any) => {
  result.value = item
  httpStatus.value = item.title.split(' ')[0]
}

const getTagColor = (category: string) => {
  const colors = {
    '1xx': 'blue',
    '2xx': 'green',
    '3xx': 'orange',
    '4xx': 'red',
    '5xx': 'purple'
  }
  return colors[category.split(' ')[0]] || 'gray'
}

const getTagColorByCode = (code: string) => {
  return getTagColor(code[0] + 'xx')
}
</script>

<template>
    <div class="http-status-container">

        <!-- 主要内容区域 -->
        <div class="content-wrapper">
            <!-- 分类导航 -->
            <div class="category-nav">
                <div class="nav-header">状态码分类</div>
                <a-input 
                    v-model:value="httpStatus"
                    placeholder="输入状态码 (如 404)"
                    size="middle"
                    @change="handleSearch"
                >
                    <template #prefix>
                        <SearchOutlined class="search-icon" />
                    </template>
                </a-input>
                <a-collapse v-model:activeKey="activeCategory" accordion>
                    <a-collapse-panel 
                        v-for="category in StatusList" 
                        :key="category.title"
                        :header="category.title"
                        class="category-panel"
                    >
                        <div class="tags-container">
                            <a-tag 
                                v-for="item in category.child" 
                                :key="item.title"
                                :color="getTagColor(category.title)"
                                class="status-tag"
                                @click="selectStatus(item)"
                            >
                                {{ item.title.split(' ')[0] }}
                            </a-tag>
                        </div>
                    </a-collapse-panel>
                </a-collapse>
            </div>

            <!-- 结果展示 -->
            <div class="result-card" :class="{ 'has-result': result }">
                <div v-if="result" class="status-detail">
                    <div class="status-header">
                        <div class="status-title">
                            <h2 class="status-code">
                                {{ result.title.split(' ')[0] }}
                            </h2>
                            <div class="status-text">
                                {{ result.title.split(' ').slice(1).join(' ') }}
                            </div>
                        </div>
                        <div class="status-meta">
                            <a-tag :color="getTagColorByCode(result.title.split(' ')[0])" class="category-tag">
                                {{ result.title.split(' ')[0][0] + 'xx' }}
                            </a-tag>
                            <div class="last-search">
                                <ClockCircleOutlined class="meta-icon" />
                                <span>{{ lastSearchTime }}</span>
                            </div>
                        </div>
                    </div>
                    <a-divider class="custom-divider" />
                    <div class="status-content">
                        <p>{{ result.content }}</p>
                    </div>
                </div>
                
                <div v-else class="empty-state">
                    <div class="empty-animation">
                        <SmileOutlined class="empty-icon" />
                    </div>
                    <p>输入状态码或从左侧分类中选择</p>
                </div>
            </div>
        </div>
    </div>
</template>

<style scoped>
.http-status-container {
    max-width: 1400px;
    margin: 0 auto;
    padding: 2rem;
    min-height: 100vh;
    background: linear-gradient(135deg, #f5f7fa 0%, #e4e7eb 100%);
}

.search-section {
    text-align: center;
    margin-bottom: 3rem;
    padding: 2rem;
    background: rgba(255, 255, 255, 0.8);
    border-radius: 16px;
    box-shadow: 0 8px 30px rgba(0, 0, 0, 0.1);
    backdrop-filter: blur(10px);
}

.search-title h1 {
    font-size: 2.5rem;
    color: #2c3e50;
    margin-bottom: 0.5rem;
    font-weight: 600;
}

.subtitle {
    color: #666;
    font-size: 1.1rem;
    margin-bottom: 2rem;
}

.search-box {
    max-width: 600px;
    margin: 0 auto;
}

.search-icon {
    color: #1890ff;
    font-size: 18px;
}

.content-wrapper {
    display: grid;
    grid-template-columns: 320px 1fr;
    gap: 2rem;
    position: relative;
}

.category-nav {
    background: rgba(255, 255, 255, 0.9);
    border-radius: 16px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
    overflow: hidden;
    backdrop-filter: blur(10px);
    height: fit-content;
}

.nav-header {
    padding: 1rem;
    font-size: 1.2rem;
    font-weight: 500;
    color: #2c3e50;
    background: rgba(255, 255, 255, 0.9);
    border-bottom: 1px solid #eee;
}

.category-panel :deep(.ant-collapse-header) {
    font-weight: 500;
    background: rgba(255, 255, 255, 0.7) !important;
    transition: all 0.3s ease;
}

.category-panel :deep(.ant-collapse-header:hover) {
    background: rgba(255, 255, 255, 0.9) !important;
}

.tags-container {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 8px;
}

.status-tag {
    margin: 0;
    cursor: pointer;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    font-size: 0.9rem;
    padding: 4px 12px;
}

.status-tag:hover {
    transform: translateY(-2px) scale(1.05);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.result-card {
    background: rgba(255, 255, 255, 0.9);
    border-radius: 16px;
    padding: 2rem;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
    backdrop-filter: blur(10px);
    transition: all 0.3s ease;
    min-height: 600px;
}

.result-card.has-result {
    transform: translateY(0);
    opacity: 1;
}

.status-detail {
    animation: fadeIn 0.5s ease;
}

.status-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: 2rem;
}

.status-title {
    display: flex;
    align-items: baseline;
    gap: 1rem;
}

.status-code {
    font-size: 4rem;
    margin: 0;
    font-weight: 700;
    background: linear-gradient(135deg, #1890ff, #36cfc9);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    line-height: 1;
}

.status-text {
    font-size: 1.5rem;
    color: #666;
}

.status-meta {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 1rem;
}

.category-tag {
    font-size: 1rem;
    padding: 4px 12px;
}

.last-search {
    display: flex;
    align-items: center;
    gap: 8px;
    color: #666;
    font-size: 0.9rem;
}

.status-content {
    font-size: 1.1rem;
    line-height: 1.8;
    color: #2c3e50;
    padding: 1rem;
    background: rgba(255, 255, 255, 0.5);
    border-radius: 8px;
    margin-top: 1rem;
}

.empty-state {
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    color: #666;
}

.empty-animation {
    margin-bottom: 2rem;
}

.empty-icon {
    font-size: 5rem;
    color: #1890ff;
    animation: float 3s ease-in-out infinite;
}

@keyframes fadeIn {
    from {
        opacity: 0;
        transform: translateY(20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes float {
    0% {
        transform: translateY(0px);
    }
    50% {
        transform: translateY(-20px);
    }
    100% {
        transform: translateY(0px);
    }
}
</style>
